﻿package cn.jingsheng.backup.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 数据库连接工具类
 * 
 * @author 李晓丹
 * 
 */
public class DbUtil {
	// 日志记录
	private static Log log = LogFactory.getLog(DbUtil.class);
	// 数据库连接对象
	private Connection conn = null;
	// 最后操作时间
	private long lastInvoke = 0;
	public static final String DATABASE_TYPE = SystemConfig.getProperties("Database_Type");
	// 驱动类
	public static final String DRIVER_CLASS = SystemConfig.getProperties(DATABASE_TYPE + "_Class");
	// 数据库连接字符串
	public static final String DRIVER_URL = SystemConfig.getProperties(DATABASE_TYPE + "_URL");
	// 数据库用户名
	public static final String DRIVER_USER = SystemConfig.getProperties(DATABASE_TYPE + "_User");
	// 数据库密码
	public static final String DRIVER_PASSWORD = SystemConfig.getProperties(DATABASE_TYPE + "_Password");
	// 单例模式
	public static DbUtil databaseUtil = new DbUtil();

	private DbUtil() {
		getConnection();
	}

	/**
	 * 建立数据库连接
	 */
	private Connection getConnection() {
		// 最后访问时间与当前时间比较
		long now = DateTimeUtil.getCurrentDate().getTime();
		if (conn == null || now - lastInvoke > 1000 * 60) {
			close(conn);
			try {
				/** 获取数据库连接 */
				Class.forName(DRIVER_CLASS);
				conn = DriverManager.getConnection(DRIVER_URL, DRIVER_USER, DRIVER_PASSWORD);
				/** 自动关闭数据库连接 */
				Runtime.getRuntime().addShutdownHook(new Thread() {
					@Override
					public void run() {
						DbUtil.close(conn);
					}
				});
			} catch (SQLException e) {
				log.error(e.getMessage(), e);
				throw new RuntimeException(e);
			} catch (ClassNotFoundException e) {
				log.error(e.getMessage(), e);
				throw new RuntimeException(e);
			}
		}
		lastInvoke = now;
		return conn;
	}

	/**
	 * 根据查询语句 生成预编译SQL对象
	 * 
	 * @param str
	 *            查询SQL语句
	 * @return
	 */
	public static PreparedStatement prepareStatement(String str) {
		return prepareStatement(str, new Object[] {});
	}

	/**
	 * 根据查询语句 生成预编译SQL对象
	 * 
	 * @param str
	 *            查询SQL语句
	 * @param array
	 *            查询SQL语句参数
	 * @return
	 */
	public static PreparedStatement prepareStatement(String str, Object... array) {
		// 输出调试信息
		log.debug(str);
		System.out.println(str);
		log.debug(array);
		// 预编译SQL对象
		PreparedStatement ps = null;
		try {
			ps = databaseUtil.getConnection().prepareStatement(str);
			// 参数赋值
			for (int i = 0; array != null && i != array.length; i++) {
				ps.setObject(i + 1, array[i]);
			}
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
		return ps;
	}

	/**
	 * 关闭 预编译SQL对象
	 * 
	 * @param ps
	 *            预编译SQL对象
	 */
	public static void close(PreparedStatement ps) {
		try {
			if (ps != null)
				ps.close();
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}

	/**
	 * 关闭 查询结果集
	 * 
	 * @param rs
	 *            查询结果集
	 */
	public static void close(ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
		} catch (SQLException e) {
			log.error(e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}

	/**
	 * 关闭 数据库连接
	 * 
	 * @param conn
	 *            数据库连接
	 */
	public static void close(Connection conn) {
		final Connection toClose = conn;
		new Thread() {
			@Override
			public void run() {
				try {
					if (toClose != null)
						toClose.close();
				} catch (Exception e) {
					log.error(e.getMessage(), e);
					// throw new RuntimeException(e);
				}
			}
		}.start();

	}
	
}
